package com.sixbro.shiro.jwt.exception;

import com.bxs.rbac.shiro.jwt.common.ApiResultCode;
import com.bxs.response.ApiResponse;
import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * <p>
 * 自定义异常处理类
 * 注意这个统一异常处理器只对认证过的用户调用接口中的异常有作用，对AuthenticationException没有用
 * </p>
 *
 * @Author: Mr.Lu
 * @Since: 2020/6/17 16:58
 */
@RestControllerAdvice
public class ExceptionResolver {
    private final Logger _logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 捕捉shiro的异常
     * @param exception
     * @return
     */
    @ExceptionHandler(ShiroException.class)
    public ApiResponse handle(ShiroException exception) {
        _logger.info("---------    ShiroException   ----------");
        return ApiResponse.fail(ApiResultCode.FAILED.code, exception.getMessage(), null);
    }

    /**
     * 捕捉UnauthorizedException
     * @param exception
     * @return
     */
    @ExceptionHandler(AuthorizationException.class)
    public ApiResponse handle(AuthorizationException exception) {
        _logger.info("---------    AuthorizationException   ----------");
        return ApiResponse.fail(ApiResultCode.USER_NO_PERMITION.code, exception.getMessage(), null);
    }

    /**
     * 捕捉UnauthorizedException
     * @param exception
     * @return
     */
    @ExceptionHandler(AuthenticationException.class)
    public ApiResponse handle(AuthenticationException exception) {
        _logger.info("---------    AuthenticationException   ----------");
        return ApiResponse.fail(ApiResultCode.INVALID_USERNAME_PASSWORD.code, exception.getMessage(), null);
    }

    /**
     * 捕捉其他所有异常
     * @param request
     * @param throwable
     * @return
     */
    @ExceptionHandler(Exception.class)
    ///@ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResponse globalException(HttpServletRequest request, Throwable throwable) {
        _logger.info("---------    globalException   ----------");
        return ApiResponse.fail(ApiResultCode.FAILED.code, "其他异常", null);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }
}
